package windbell.domain.risk.impl;

import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import windbell.domain.risk.RiskCheckTemplate;
import windbell.domain.risk.RiskCheckTemplateItem;
import windbell.domain.risk.RiskCheckTemplateOwner;
import windbell.domain.risk.RiskCheckTemplateStatus;
import windbell.domain.risk.impl.BaseHasSimplePyImpl;
import windbell.domain.risk.impl.RiskCheckTemplateItemImpl;
import windbell.domain.risk.impl.RiskCheckTemplateOwnerImpl;
import windbell.domain.risk.proxy.RiskCheckTemplateProxy;

@Entity
@DiscriminatorValue("RISKCHECKTEMPLATE_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "riskchecktemplate")
public class RiskCheckTemplateImpl extends BaseHasSimplePyImpl implements RiskCheckTemplate {
  public RiskCheckTemplateImpl() {
    super();
  }
  
  public RiskCheckTemplateImpl(final RiskCheckTemplateOwner owner) {
    super();
    this.owner = owner;
  }
  
  private RiskCheckTemplateStatus Status;
  
  public RiskCheckTemplateStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    Status=RiskCheckTemplateStatus.created;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckTemplateEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _update(final Procedure1<? super RiskCheckTemplate> updater) {
    updater.apply(this);
  }
  
  public void update(final Procedure1<? super RiskCheckTemplate> updater) {
    if(Status==RiskCheckTemplateStatus.created){
    	_update(updater);
    	getModelObjectLogService().createLog(this,"Status","update");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckTemplateEventsManager.class).fireUpdate(this,updater);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _delete() {
    getObjectFactory().delete(this);
    
  }
  
  public void delete() {
    if(Status==RiskCheckTemplateStatus.created){
    	_delete();
    	getModelObjectLogService().createLog(this,"Status","delete");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckTemplateEventsManager.class).fireDelete(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _addCheckItem(final RiskCheckTemplateItem item) {
    
    this.addtoCheckList(item);
  }
  
  public void addCheckItem(final RiskCheckTemplateItem item) {
    if(Status==RiskCheckTemplateStatus.created){
    	_addCheckItem(item);
    	getModelObjectLogService().createLog(this,"Status","addCheckItem");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckTemplateEventsManager.class).fireAddCheckItem(this,item);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isCreated() {
    return windbell.domain.risk.RiskCheckTemplateStatus.created==Status;
  }
  
  @JoinColumn(name = "owner_id")
  @ManyToOne(targetEntity = RiskCheckTemplateOwnerImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RiskCheckTemplateOwner owner;
  
  public RiskCheckTemplateOwner getOwner() {
    return this.owner;
  }
  
  public RiskCheckTemplate setOwner(final RiskCheckTemplateOwner owner) {
    this.owner = owner;
    return this;			
    
  }
  
  private String description;
  
  public String getDescription() {
    return this.description;
  }
  
  public RiskCheckTemplate setDescription(final String description) {
    this.description = description;
    return this;			
    
  }
  
  @ManyToMany(targetEntity = RiskCheckTemplateItemImpl.class)
  @JoinTable(name = "m2m_riskchecktemplate_checklist", joinColumns = @JoinColumn(name = "riskchecktemplate_id") , inverseJoinColumns = @JoinColumn(name = "riskCheckTemplateItem_inv_id") )
  private Collection<RiskCheckTemplateItem> checkList = new java.util.ArrayList<windbell.domain.risk.RiskCheckTemplateItem>();;
  
  public Collection<RiskCheckTemplateItem> getCheckList() {
    return this.checkList;
  }
  
  public RiskCheckTemplate setCheckList(final Iterable<RiskCheckTemplateItem> checkList) {
    removeAllCheckList();
    for(RiskCheckTemplateItem ca : checkList){
    	addtoCheckList(ca);
    }
    return this;		
    
  }
  
  public RiskCheckTemplate addtoCheckList(final RiskCheckTemplateItem riskCheckTemplateItem) {
    this.checkList.add(riskCheckTemplateItem);
    return this;
    
  }
  
  public RiskCheckTemplate removeAllCheckList() {
    this.checkList.clear();
    return this;	
    
  }
  
  public RiskCheckTemplate removeFromCheckList(final RiskCheckTemplateItem riskCheckTemplateItem) {
    this.checkList.remove(riskCheckTemplateItem);
    return this;
    
  }
  
  public Collection<RiskCheckTemplateItem> getRiskCheckTemplateItems() {
    return this.checkList;
  }
  
  public static RiskCheckTemplate create(final RiskCheckTemplateOwner owner, final IObjectFactory objectFactory) {
    windbell.domain.risk.RiskCheckTemplate riskCheckTemplate = new windbell.domain.risk.impl.RiskCheckTemplateImpl(
    	owner
    );
    objectFactory.create(riskCheckTemplate);
    riskCheckTemplate.start();
    return riskCheckTemplate;			
    
  }
  
  public static RiskCheckTemplate createRiskCheckTemplateImpl(final RiskCheckTemplateOwner owner, final IObjectFactory objectFactory, final Procedure1<RiskCheckTemplate> init) {
    windbell.domain.risk.RiskCheckTemplate riskCheckTemplate = new windbell.domain.risk.impl.RiskCheckTemplateImpl(
    	owner
    );
    objectFactory.create(riskCheckTemplate);
    init.apply(riskCheckTemplate);
    riskCheckTemplate.start();
    return riskCheckTemplate;			
    
  }
  
  public RiskCheckTemplateProxy toProxy() {
    windbell.domain.risk.proxy.RiskCheckTemplateProxy proxy = new windbell.domain.risk.proxy.RiskCheckTemplateProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
